package container.map;

import lombok.AllArgsConstructor;
import lombok.SneakyThrows;

import java.util.HashMap;
import java.util.Objects;
import java.util.UUID;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 线程不安全
 */
public class T02_HashMap {
    static int threadNum = 999;
    static HashMap<String, Object> m = new HashMap<>(1);
    static ExecutorService es = Executors.newFixedThreadPool(threadNum);
    static CountDownLatch endGate = new CountDownLatch(threadNum);

    static class MyThread extends Thread {
        @Override
        public void run() {
            for (int i = 0; i < 999; i++) {
                m.put(UUID.randomUUID().toString(), i);
            }
            endGate.countDown();
        }
    }

    @SneakyThrows
    public static void main(String[] args) {
        long start = System.currentTimeMillis();
        for (int i = 0; i < threadNum; i++) {
            es.submit(new MyThread());
        }
        endGate.await();
        es.shutdown();
        while (true) {
            if (es.isTerminated()) {
                System.out.println("所有的子线程都结束了！");
                break;
            }
            Thread.sleep(1000);
        }
        long end = System.currentTimeMillis();
        System.out.println("time: " + (end - start));
        System.out.println("size: " + m.size());

        System.out.println("========================================================================");

        HashMap<Person, String> map = new HashMap<>();
        Person person = new Person("jhxxb");
        // put 到 hashmap 中去
        map.put(person, "jhxxb");
        // get 取出，从逻辑上讲应该能输出 jhxxb
        System.out.println("result: " + map.get(new Person("jhxxb")));

        System.out.println(person.hashCode());
        System.out.println(new Person("jhxxb").hashCode());
    }

    @AllArgsConstructor
    // @EqualsAndHashCode
    private static class Person { // 理解 equals 和 hashCode
        String name;

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            Person person = (Person) o;
            return Objects.equals(name, person.name);
        }

        // @Override
        // public int hashCode() {
        //     return Objects.hash(name);
        // }
    }
}